package cn.dengta.webapp.user.service;

import java.io.IOException;
import java.math.BigDecimal;
import java.net.URI;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Map;
import javax.annotation.Nullable;

import cn.dengta.common.alarm.dingtalk.BugSendService;
import cn.dengta.common.model.Messager;
import cn.dengta.common.util.SpringUtil;
import cn.dengta.context.model.WesKit;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import me.codeplayer.util.JSONUtil;
import me.codeplayer.util.StringUtil;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;

/**
 * 创蓝短信接口
 * https://www.chuanglan.com/document/6110e57909fd9600010209de/62b3dc1d272e290001af3e75
 */
@Slf4j
@Component
public class ClSmsService extends AbstractSmsService {

	static final URI API = URI.create("https://sgap.253.com/send/json");
	static final URI API_VAR = URI.create("https://smssh1.253.com/msg/variable/json");

	public static Messager<String> doSend(boolean isVar, URI url, String requestBody) {
		url = StringUtil.isEmpty(url) ? (isVar ? API_VAR : API) : url;
		String body = doSendInternal(url, requestBody);
		JSONObject json = null;
		if (StringUtil.notEmpty(body)) {
			json = JSONUtil.parseObject(body);
			int code = json.getIntValue("code");
			if (code == 119) { // 如果提示节点不正确，则使用旧版 API 进行发送
				if (!isVar) {
					log.warn("短信节点不正确，切换为国内节点：{}", requestBody);
					body = doSendInternal(URI.create("https://intapi.253.com/send/json"), requestBody);
					if (StringUtil.notEmpty(body)) {
						json = JSONUtil.parseObject(body);
						code = json.getIntValue("code");
					}
				}
			} else if (code == 110) { // 账户余额不足
				SpringUtil.getBean(BugSendService.class).sendBugMsg("短信余额不足，请立即充值！");
			}
			if (code == 0) {
				return Messager.hideData(body).setExtra(json);
			}
		}
		return Messager.<String>status("networkError").setPayload(body).setExtra(json);
	}

	@Nullable
	static String doSendInternal(URI api, String requestBody) {
		HttpRequest request = requestBuilder(HttpMethod.POST, api, requestBody, true)
				.build();

		Exception ex = null;
		String body = null;
		try {
			HttpResponse<String> response = httpClient.send(request, responseBodyHandler);
			body = response.body();
		} catch (IOException | InterruptedException e) {
			ex = e;
			return null;
		} finally {
			if (ex == null) {
				log.info("【短信】接口请求地址：{}，请求参数：{}，返回数据：{}", api, requestBody, body);
			} else {
				log.error("【短信】接口请求地址：" + api + "，请求参数：" + requestBody + "，返回数据：" + body, ex);
			}
		}
		return body;
	}

	static final String account = "I6190742", password = "q4v3fri1S39639";
	static final String account_cn = "YZM3194370", password_cn = "31qP58HTi35582";

	static final String account_biz_cn = "M0408865", password_biz_cn = "lmC1Oayk6c1629", extend_cn = "355891";

	/**
	 * 查询短信余额
	 */
	public BigDecimal queryBalance(WesKit wesKit) throws IllegalArgumentException {
		final Map<String, String> params = Map.of("account", wesKit.isInterior() ? account_cn : account,
				"password", wesKit.isInterior() ? password_cn : password);
		final URI api = URI.create("https://sgap.253.com/balance/json");
		final URI api_cn = URI.create("https://smssh1.253.com/msg/balance/json");
		final String requestBody = JSON.toJSONString(params);
		final String body = doSendInternal(wesKit.isInterior() ? api_cn : api, requestBody);
		if (StringUtil.notEmpty(body)) {
			JSONObject json = JSONUtil.parseObject(body);
			int code = json.getIntValue("code");
			if (code == 0) {
				return json.getBigDecimal("balance");
			}
		}
		throw new IllegalArgumentException("查询短信商户余额时出错");
	}

	@Override
	public Messager<String> send(WesKit wesKit, String content, String params, String to) {
		// to的格式： 86-18221391549
		final Map<String, String> request = wesKit.isInterior() ?
				Map.of(
						"account", account_cn,
						"password", password_cn,
						"msg", content,
						"params", params,
						"report", "true"
				)
				: Map.of(
				"account", account,
				"password", password,
				"msg", content,
				"mobile", to.replace("-", "")
		);
		return doSend(wesKit.isInterior(), null, JSON.toJSONString(request));
	}

	@Override
	public Messager<String> sendBiz(WesKit wesKit, String content, String phone) {
		if (!wesKit.isInterior()) {
			return Messager.error("暂不支持国际营销短信");
		}
		Map<String, String> request = Map.of(
				"account", account_biz_cn,
				"password", password_biz_cn,
				"msg", content,
				"phone", phone,
				"report", "true"
		);
		return doSend(false, URI.create("https://smssh1.253.com/msg/v1/send/json"), JSON.toJSONString(request));
	}

}
